﻿using System;
using System.AutoUpdate.Library;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace System.AutoUpdate.Security
{
    public static class HashAlgorithmProvider
    {
        public static bool HashFileMatch (string filename, string hash, HashAlgorithmType type)
        {
            string fileHash = CalculateFileHash (filename, type);

            return (fileHash == hash);
        }

        public static bool HashTextMatch (string text, string hash, HashAlgorithmType type)
        {
            string fileHash = CalculateTextHash(text, type);

            return (fileHash == hash);
        }

        public static bool HashFileMatch (UpdateVersionInfo version)
        {
            return HashFileMatch (version.File.AbsoluteLocalPath, version.File.Hash, version.File.HashType);
        }

        public static string CalculateFileHash (string filename, HashAlgorithmType type)
        {
            HashAlgorithm algorithm = null;

            switch (type)
            {
                case HashAlgorithmType.Md5:
                    algorithm = new MD5CryptoServiceProvider ();

                    break;
                case HashAlgorithmType.Sha1:
                    algorithm = new SHA1CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha256:
                    algorithm = new SHA256CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha384:
                    algorithm = new SHA384CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha512:
                    algorithm = new SHA512CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Ripemd:
                    algorithm = new RIPEMD160Managed();

                    break;
            }

            FileStream file = new FileStream(filename, FileMode.Open);

            if (algorithm != null)
            {
                byte[] hash = algorithm.ComputeHash (file);

                return ByteArrayToHexString (hash);
            }

            return "";
        }

        public static string CalculateTextHash (string text, HashAlgorithmType type)
        {
            HashAlgorithm algorithm = null;

            switch (type)
            {
                case HashAlgorithmType.Md5:
                    algorithm = new MD5CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha1:
                    algorithm = new SHA1CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha256:
                    algorithm = new SHA256CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha384:
                    algorithm = new SHA384CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Sha512:
                    algorithm = new SHA512CryptoServiceProvider();

                    break;
                case HashAlgorithmType.Ripemd:
                    algorithm = new RIPEMD160Managed();

                    break;
            }

            if (algorithm != null)
            {
                byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes (text));

                return ByteArrayToHexString(hash);
            }

            return "";
        }

        private static string ByteArrayToHexString (byte[] bytes)
        {
            return BitConverter.ToString (bytes).Replace ("-", "");
        }
    }
}
